package br.com.mftc.efitness.negocio;

import java.util.List;

import br.com.mftc.efitness.basicas.PerfilDeUsuario;
import br.com.mftc.efitness.dados.DadosPerfilDoUsuario;
import br.com.mftc.efitness.dados.IDadosPerfilDeUsuario;
import br.com.mftc.efitness.excecoes.ExcecaoBuscaSemResultados;
import br.com.mftc.efitness.excecoes.ExcecaoCamposObrigatoriosNaoPreenchidos;
import br.com.mftc.efitness.excecoes.ExcecaoCaracteresEspeciaisNaoSaoPermitidos;
import br.com.mftc.efitness.excecoes.ExcecaoGeral;
import br.com.mftc.efitness.excecoes.ExcecaoListaDeRegistrosDesatualizada;
import br.com.mftc.efitness.excecoes.ExcecaoNegocio;
import br.com.mftc.efitness.excecoes.ExcecaoRegistroDesatualizado;
import br.com.mftc.efitness.util.Util;
import br.com.mftc.efitness.util.Variaveis;

public class ControladorPerfilDeUsuario {

	private final IDadosPerfilDeUsuario dadosPerfilDeUsuario;
	
	private final ControladorUsuarioDoSistema controladorUsuarioDoSistema;
	
	public ControladorPerfilDeUsuario () {
		dadosPerfilDeUsuario = new DadosPerfilDoUsuario();
		
		controladorUsuarioDoSistema = new ControladorUsuarioDoSistema();
	}
	
	public PerfilDeUsuario validarDados(PerfilDeUsuario perfilDeUsuario) throws ExcecaoCamposObrigatoriosNaoPreenchidos, ExcecaoCaracteresEspeciaisNaoSaoPermitidos, ExcecaoNegocio {
		if (perfilDeUsuario == null) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_INFORME_REGISTRO_INVALIDO);
		} else if (perfilDeUsuario.getNome() == null || perfilDeUsuario.getNome().trim().equals("")) {
			throw new ExcecaoCamposObrigatoriosNaoPreenchidos();
		} else if (Util.contemCaracteresEspeciais(perfilDeUsuario.getNome())) {
			throw new ExcecaoCaracteresEspeciaisNaoSaoPermitidos();
		} else if (perfilDeUsuario.getDescricao() != null && Util.contemCaracteresEspeciais(perfilDeUsuario.getDescricao())) {
			throw new ExcecaoCaracteresEspeciaisNaoSaoPermitidos();
		} else {
			return perfilDeUsuario;
		}
	}
	
	public PerfilDeUsuario inserir(PerfilDeUsuario perfilDeUsuario) throws ExcecaoCamposObrigatoriosNaoPreenchidos, ExcecaoCaracteresEspeciaisNaoSaoPermitidos, ExcecaoNegocio, ExcecaoGeral {
		perfilDeUsuario = validarDados(perfilDeUsuario);
		
		perfilDeUsuario.setDataDeCriacao(Util.agora());
		perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());
		
		try {						
			dadosPerfilDeUsuario.iniciarTransacao();
			dadosPerfilDeUsuario.inserir(perfilDeUsuario);
			dadosPerfilDeUsuario.finalizarTransacao();
			
			return perfilDeUsuario;
		} catch (Exception excecao) {
			try {
				dadosPerfilDeUsuario.desfazerTransacao();
				throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_INSERIR);
			} catch (ExcecaoNegocio excecaoAux) {
				throw excecaoAux;
			} catch (Exception excecaoAux) {
				throw new ExcecaoGeral();
			}
		}
	}
	
	public void alterar(PerfilDeUsuario perfilDeUsuario) throws ExcecaoCamposObrigatoriosNaoPreenchidos, ExcecaoCaracteresEspeciaisNaoSaoPermitidos, ExcecaoRegistroDesatualizado, ExcecaoNegocio, ExcecaoGeral  {
		if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()).getVersao() != perfilDeUsuario.getVersao()) {
			throw new ExcecaoRegistroDesatualizado();
		} else {			
			perfilDeUsuario = validarDados(perfilDeUsuario);
			
			perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());
			
			try {				
				dadosPerfilDeUsuario.iniciarTransacao();
				dadosPerfilDeUsuario.alterar(perfilDeUsuario);
				dadosPerfilDeUsuario.finalizarTransacao();
			} catch (Exception excecao) {
				try {
					dadosPerfilDeUsuario.desfazerTransacao();
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_ALTERAR);
				} catch (ExcecaoNegocio excecaoAux) {
					throw excecaoAux;
				} catch (Exception excecaoAux) {
					throw new ExcecaoGeral();
				}
			}
		}
	}
	
	public void ativar(PerfilDeUsuario perfilDeUsuario) throws ExcecaoRegistroDesatualizado, ExcecaoNegocio, ExcecaoGeral {
		if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()).getVersao() != perfilDeUsuario.getVersao()) {
			throw new ExcecaoRegistroDesatualizado();
		} else {
			perfilDeUsuario.setStatusAtivacao(true);
			perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());

			try {	
				dadosPerfilDeUsuario.iniciarTransacao();
				dadosPerfilDeUsuario.alterar(perfilDeUsuario);
				dadosPerfilDeUsuario.finalizarTransacao();
			} catch (Exception excecao) {
				try {
					dadosPerfilDeUsuario.desfazerTransacao();
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_ATIVAR);
				} catch (ExcecaoNegocio excecaoAux) {
					throw excecaoAux;
				} catch (Exception excecaoAux) {
					throw new ExcecaoGeral();
				}
			}
		}
	}
	
	public void ativarLista(List<PerfilDeUsuario> perfisDeUsuario) throws ExcecaoListaDeRegistrosDesatualizada, ExcecaoNegocio, ExcecaoGeral {
		int quantidadeDePerfis = perfisDeUsuario.size();
		PerfilDeUsuario perfilDeUsuario;
		
		try {
			dadosPerfilDeUsuario.iniciarTransacao();
			
			for (int indexPerfil = 0; indexPerfil < quantidadeDePerfis; indexPerfil++) {
				perfilDeUsuario = perfisDeUsuario.get(indexPerfil);
				if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()).getVersao() != perfilDeUsuario.getVersao()) {
					throw new ExcecaoListaDeRegistrosDesatualizada();
				} else {
					perfilDeUsuario.setStatusAtivacao(true);
					perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());
					
					dadosPerfilDeUsuario.alterar(perfilDeUsuario);
				}
			}
			
			dadosPerfilDeUsuario.finalizarTransacao();
		} catch (ExcecaoListaDeRegistrosDesatualizada excecao) {
			dadosPerfilDeUsuario.desfazerTransacao();
			throw excecao;
		} catch (Exception excecao) {
			try {
				dadosPerfilDeUsuario.desfazerTransacao();
				throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_ATIVAR_LISTA);
			} catch (ExcecaoNegocio excecaoAux) {
				throw excecaoAux;
			} catch (Exception excecaoAux) {
				throw new ExcecaoGeral();
			}
		}
	}
	
	public void desativar(PerfilDeUsuario perfilDeUsuario) throws ExcecaoRegistroDesatualizado, ExcecaoNegocio, ExcecaoGeral {
		if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()).getVersao() != perfilDeUsuario.getVersao()) {
			throw new ExcecaoRegistroDesatualizado();
		} else if (!controladorUsuarioDoSistema.consultarPorPerfil(perfilDeUsuario).isEmpty()) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_DESATIVAR_PERFIL_EM_USO);
		} else {
			perfilDeUsuario.setStatusAtivacao(false);
			perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());

			try {	
				dadosPerfilDeUsuario.iniciarTransacao();
				dadosPerfilDeUsuario.alterar(perfilDeUsuario);
				dadosPerfilDeUsuario.finalizarTransacao();
			} catch (Exception excecao) {
				try {
					dadosPerfilDeUsuario.desfazerTransacao();
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_DESATIVAR);
				} catch (ExcecaoNegocio excecaoAux) {
					throw excecaoAux;
				} catch (Exception excecaoAux) {
					throw new ExcecaoGeral();
				}
			}
		}
	}
	
	public void desativarLista(List<PerfilDeUsuario> perfisDeUsuario) throws ExcecaoListaDeRegistrosDesatualizada, ExcecaoNegocio, ExcecaoGeral {
		int quantidadeDePerfis = perfisDeUsuario.size();
		PerfilDeUsuario perfilDeUsuario;
		
		try {
			dadosPerfilDeUsuario.iniciarTransacao();
			
			for (int indexPerfil = 0; indexPerfil < quantidadeDePerfis; indexPerfil++) {
				perfilDeUsuario = perfisDeUsuario.get(indexPerfil);
				if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()).getVersao() != perfilDeUsuario.getVersao()) {
					throw new ExcecaoListaDeRegistrosDesatualizada();
				} else if (!controladorUsuarioDoSistema.consultarPorPerfil(perfilDeUsuario).isEmpty()) {
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_DESATIVAR_ITEM_LISTA_EM_USO);
				} else {
					perfilDeUsuario.setStatusAtivacao(false);
					perfilDeUsuario.setDataDeUltimaAtualizacao(Util.agora());
					
					dadosPerfilDeUsuario.alterar(perfilDeUsuario);
				}
			}
			
			dadosPerfilDeUsuario.finalizarTransacao();
		} catch (ExcecaoListaDeRegistrosDesatualizada excecao) {
			dadosPerfilDeUsuario.desfazerTransacao();
			throw excecao;
		} catch (ExcecaoNegocio excecao) {
			dadosPerfilDeUsuario.desfazerTransacao();
			throw excecao;
		} catch (Exception excecao) {
			try {
				dadosPerfilDeUsuario.desfazerTransacao();
				throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_DESATIVAR_LISTA);
			} catch (ExcecaoNegocio excecaoAux) {
				throw excecaoAux;
			} catch (Exception excecaoAux) {
				throw new ExcecaoGeral();
			}
		}
	}
	
	public void remover(PerfilDeUsuario perfilDeUsuario) throws ExcecaoNegocio, ExcecaoGeral {
		if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()) == null) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER_REGISTRO_JA_REMOVIDO);
		} else if (!controladorUsuarioDoSistema.consultarPorPerfil(perfilDeUsuario).isEmpty()) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER_PERFIL_EM_USO);
		} else {
			try {
				dadosPerfilDeUsuario.iniciarTransacao();
				dadosPerfilDeUsuario.remover(perfilDeUsuario);
				dadosPerfilDeUsuario.finalizarTransacao();
			} catch (Exception excecao) {
				try {
					dadosPerfilDeUsuario.desfazerTransacao();
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER);
				} catch (ExcecaoNegocio excecaoAux) {
					throw excecaoAux;
				} catch (Exception excecaoAux) {
					throw new ExcecaoGeral();
				}
			}
		}
	}
	
	public void removerLista(List<PerfilDeUsuario> perfisDeUsuario) throws ExcecaoNegocio, ExcecaoGeral {
		int quantidadeDePerfis = perfisDeUsuario.size();
		PerfilDeUsuario perfilDeUsuario;
		
		try {
			dadosPerfilDeUsuario.iniciarTransacao();
			
			for (int indexPerfil = 0; indexPerfil < quantidadeDePerfis; indexPerfil++) {
				perfilDeUsuario = perfisDeUsuario.get(indexPerfil);
				if (dadosPerfilDeUsuario.consultarPorId(perfilDeUsuario.getCodigo()) == null) {
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER_ITEM_LISTA_JA_REMOVIDO);
				} else if (!controladorUsuarioDoSistema.consultarPorPerfil(perfilDeUsuario).isEmpty()) {
					throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER_ITEM_LISTA_EM_USO);
				} else {
					dadosPerfilDeUsuario.remover(perfilDeUsuario);
				}
			}
			
			dadosPerfilDeUsuario.finalizarTransacao();
		} catch (ExcecaoNegocio excecao) {
			dadosPerfilDeUsuario.desfazerTransacao();
			throw excecao;
		} catch (Exception excecao) {
			try {
				dadosPerfilDeUsuario.desfazerTransacao();
				throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_REMOVER_LISTA);
			} catch (ExcecaoNegocio excecaoAux) {
				throw excecaoAux;
			} catch (Exception excecaoAux) {
				throw new ExcecaoGeral();
			}
		}
	}

	public List<PerfilDeUsuario> consultarTodos() throws ExcecaoNegocio, ExcecaoBuscaSemResultados {
		List<PerfilDeUsuario> perfisDeUsuario = null;
		
		try {
			perfisDeUsuario = dadosPerfilDeUsuario.consultarTodos();			
		} catch (Exception excecao) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_CONSULTAR_TODOS);
		}
		
		if (perfisDeUsuario.isEmpty()) {
			throw new ExcecaoBuscaSemResultados();
		} else {
			return perfisDeUsuario;
		}
	}
	
	public List<PerfilDeUsuario> consultarPorNome(String nome) throws ExcecaoNegocio, ExcecaoBuscaSemResultados, ExcecaoCaracteresEspeciaisNaoSaoPermitidos {
		if (nome == null) {
			throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_CONSULTAR_POR_NOME_INFORME_NOME);
		} else if (Util.contemCaracteresEspeciais(nome)) {
			throw new ExcecaoCaracteresEspeciaisNaoSaoPermitidos();
		} else {
		
			List<PerfilDeUsuario> perfisDeUsuario = null;
			
			try {
				perfisDeUsuario = dadosPerfilDeUsuario.consultarPorNome(nome);
			} catch (Exception excecao) {
				throw new ExcecaoNegocio(Variaveis.EXCECAO_PERFIL_DE_USUARIO_FALHA_CONSULTAR_POR_NOME);
			}
			
			if (perfisDeUsuario.isEmpty()) {
				throw new ExcecaoBuscaSemResultados();
			} else {				
				return perfisDeUsuario;
			}
		}
	}
}
